#pragma once

#include <string.h>

#include "Command.h"
#include "String.h"

typedef struct PathInfo {
    char **path;
    int pathSize;
    int fromRoot; // 布尔类型
} PathInfo;

typedef struct CreateFileParams {
    PathInfo *pathInfo;
    int fileSize;
} CreateFileParams;

typedef struct CreateFileResult {
    Status status;
    int fileFCBPtr;
} CreateFileResult;

// 计算总共有多少个斜杠
static int PRI_slashCount(char *path) {
    int length = (int) strlen(path);
    int count = 0;
    for (int i = 0; i < length; i++) {
        if (path[i] == '/') {
            if (path[i - 1] == '/') {
                return NOTHING; // 不能有两个连续的斜杠
            }
            count++;
        }
    }
    if (path[0] == '/') {
        count--;
    }
    if (length > 1 && path[length - 1] == '/') {
        count--;
    }
    return count;
}

static PathInfo *PathInfo_init(char *pathStr) {
    PathInfo *pathInfo = (PathInfo *) malloc(sizeof(PathInfo));
    int slashCount = PRI_slashCount(pathStr);
    RETURN_IF_TRUE(slashCount == NOTHING, NULL)
    pathInfo->fromRoot = pathStr[0] == '/';
    if (pathInfo->fromRoot && strlen(pathStr) == 1) { //  切换到根目录，路径大小为0
        pathInfo->pathSize = 0;
        pathInfo->path = NULL;
        return pathInfo;
    }
    pathInfo->pathSize = slashCount + 1;
    pathInfo->path = (char **) malloc(sizeof(char *) * (slashCount + 1));
    int i = pathStr[0] == '/' ? 1 : 0;
    int count = 0;
    int startPtr = i;
    for (; count < slashCount + 1; i++) {
        if (pathStr[i] == '/' || pathStr[i] == '\0') {
            pathStr[i] = '\0';
            pathInfo->path[count++] = pathStr + startPtr;
            startPtr = i + 1;
        }
    }
    return pathInfo;
}

static CreateFileParams *CreateFileParams_init(Command *command) {
    char *pathStr = command->parameter[0];
    PathInfo *pathInfo = PathInfo_init(pathStr);
    if (pathInfo == NULL) {
        return NULL;
    }

    CreateFileParams *createFileParams = (CreateFileParams *) malloc(sizeof(CreateFileParams));
    createFileParams->pathInfo = pathInfo;

    // 获取文件大小
    int fileSize = (int) strtol(command->parameter[1], command->parameter + 1, 10);
    RETURN_IF_TRUE(!String_equal(command->parameter[1], ""), NULL) // 转换失败直接返回空
    createFileParams->fileSize = fileSize;

    return createFileParams;
}

static CreateFileParams *CreateFileParams_init2(PathInfo *pathInfo, int fileSize) {
    CreateFileParams *createFileParams = (CreateFileParams *) malloc(sizeof(CreateFileParams));
    createFileParams->pathInfo = pathInfo;
    createFileParams->fileSize = fileSize;
    return createFileParams;
}

static CreateFileResult *CreateFileResult_init(Status status, int fileFCBPtr) {
    CreateFileResult *result = (CreateFileResult *) malloc(sizeof(CreateFileResult));
    result->status = status;
    result->fileFCBPtr = fileFCBPtr;
    return result;
}

static void PathInfo_release(PathInfo **pathInfo) {
    PathInfo *object = *pathInfo;
    if (object != NULL) {
        if (object->path != NULL) {
            free(object->path);
            object->path = NULL;
        }
        free(object);
        *pathInfo = NULL;
    }
}

static void CreateFileParams_release(CreateFileParams **createFileParams) {
    CreateFileParams *object = *createFileParams;
    if (object != NULL) {
        PathInfo_release(&object->pathInfo);
        object->pathInfo = NULL;
        free(object);
        *createFileParams = NULL;
    }
}
